#include "stdafx.h"
#include "Money.h"
#include "Sum.h"
#include "Bank.h"

#include <typeinfo>


Money::~Money()
{}


Money::Money( int iAmount, const std::tstring& cstrCurrency )
	: m_iAmount( iAmount )
	, m_strCurrency( cstrCurrency )
{}


MoneySp Money::Dollar( int iAmount )
{
	return std::make_shared<Money>( iAmount, _T("USD") );
}


MoneySp Money::Franc( int iAmount )
{
	return std::make_shared<Money>( iAmount, _T("CHF") );
}


bool Money::operator ==( const Expression& cRight ) const
{
	const auto& cMoney( dynamic_cast<const Money&>( cRight ) );
	return (m_iAmount == cMoney.m_iAmount)
		&& (m_strCurrency == cMoney.m_strCurrency);
}


ExpressionSp Money::operator *( int iMultiplier ) const
{
	return std::make_shared<Money>( m_iAmount * iMultiplier, m_strCurrency );
}


ExpressionSp Money::operator +( const Expression& cAddend ) const
{
	if( typeid( *this ) == typeid( cAddend ) )
	{
		const auto& cAddendMoney( dynamic_cast<const Money&>( cAddend ) );
		if( m_strCurrency == cAddendMoney.m_strCurrency )
			return std::make_shared<Money>( m_iAmount + cAddendMoney.m_iAmount, m_strCurrency );
	}

	return std::make_shared<Sum>(
		shared_from_this(),
		cAddend.shared_from_this() );
}


std::tstring Money::GetCurrency() const
{
	return m_strCurrency;
}


int Money::GetAmount() const
{
	return m_iAmount;
}


ExpressionSp Money::Reduce( const Bank& cBank, const std::tstring& cstrTo ) const
{
	int rate( cBank.FindRate( m_strCurrency, cstrTo ) );
	return std::make_shared<Money>( m_iAmount / rate, cstrTo );
}
